package com.itcp.itelpicture.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.db.DbRuntimeException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itcp.itelpicture.common.BeanUtils;
import com.itcp.itelpicture.domain.dto.community.CommentAddRequest;
import com.itcp.itelpicture.domain.dto.community.CommentQueryRequest;
import com.itcp.itelpicture.domain.po.LikeRecord;
import com.itcp.itelpicture.domain.po.User;
import com.itcp.itelpicture.domain.po.community.Comment;
import com.itcp.itelpicture.domain.po.community.CommunityPost;
import com.itcp.itelpicture.domain.vo.UserVO;
import com.itcp.itelpicture.domain.vo.communityVo.CommentVO;
import com.itcp.itelpicture.enums.CommentStatusEnum;
import com.itcp.itelpicture.enums.UserRoleEnum;
import com.itcp.itelpicture.exception.BusinessException;
import com.itcp.itelpicture.exception.ErrorCode;
import com.itcp.itelpicture.exception.ThrowUtils;
import com.itcp.itelpicture.mapper.CommentMapper;
import com.itcp.itelpicture.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itcp.itelpicture.utils.UserHolder;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 评论表 服务实现类
 * </p>
 *
 * @author wgzz
 * @since 2025-04-30
 */
@Service
@RequiredArgsConstructor
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements ICommentService {

    private final IUserService userService;

    private final ILikeRecordService likedRecordService;

    private final ICommunityPostService communityPostService;

    private final ICommunityPostService communityPostServiceImpl;

    /**
     * 分页获取一级评论
     * @param commentQueryRequest 查询条件
     * @return
     */
    @Override
    public Page<CommentVO> rootCommentVOByPage(CommentQueryRequest commentQueryRequest) {
        // 1.文章id不能为空
        if (commentQueryRequest.getPostId() == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "文章id不能为空");
        }
        // 2.获取分页记录
        Page<Comment> page = lambdaQuery()
                .eq(Comment::getPostId, commentQueryRequest.getPostId())
                .isNull(Comment::getParentId)
                .eq(Comment::getStatus, CommentStatusEnum.PASS.getValue())
                .eq(Comment::getIsDelete, 0)
                .orderByDesc(Comment::getCreateTime)
                .page(Page.of(commentQueryRequest.getCurrent(), commentQueryRequest.getPageSize()));
        List<Comment> records = page.getRecords();
        if (CollUtil.isEmpty(records)){
            return null;
        }
        // 3.封装为vo
        List<CommentVO> voList = new ArrayList<>(records.size());
        for (Comment record : records) {
            User user = userService.getById(record.getUserId());
            CommentVO commentVO = getCommentVO(record, user);
            voList.add(commentVO);
        }
        Page<CommentVO> commentVOPage = new Page<>();
        commentVOPage.setTotal(page.getTotal());
        commentVOPage.setCurrent(page.getCurrent());
        commentVOPage.setSize(page.getSize());
        commentVOPage.setRecords(voList);
        return commentVOPage;
    }


    /**
     * 将Comment转换为CommentVO
     */
    @Override
    public CommentVO getCommentVO(Comment comment, User user) {
        CommentVO commentVO = new CommentVO();
        BeanUtils.copyProperties(comment, commentVO);
        // 设置用户信息
        commentVO.setUserName(user.getUserName());
        commentVO.setUserAvatar(user.getUserAvatar());
        // 设置回复用户信息
        if (comment.getReplyUserId() != null && comment.getReplyUserId() > 0) {
            User replyUser = userService.getById(comment.getReplyUserId());
            if (replyUser != null) {
                commentVO.setReplyUserName(replyUser.getUserName());
            }
        }
        // 设置点赞状态
        Long count = likedRecordService.lambdaQuery()
                .eq(LikeRecord::getObjectId, comment.getId())
                .eq(LikeRecord::getUserId, user.getId())
                .eq(LikeRecord::getObjType, "COMMENT")
                .count();
        commentVO.setHasLiked(count > 0);

        return commentVO;
    }

    /**
     * 分页获取二级评论
     * @param commentQueryRequest 查询条件
     * @return
     */
    @Override
    public Page<CommentVO> replyCommentVOByPage(CommentQueryRequest commentQueryRequest) {
        // 1.文章id不能为空
        if (commentQueryRequest.getPostId() == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "文章id不能为空");
        }
        // 2.获取分页记录
        Page<Comment> page = lambdaQuery()
                .eq(Comment::getRootId, commentQueryRequest.getPostId())
                .ne(Comment::getId, commentQueryRequest.getPostId()) // 不包括根评论自身
                .eq(Comment::getStatus, CommentStatusEnum.PASS.getValue())
                .eq(Comment::getIsDelete, 0)
                .orderByAsc(Comment::getCreateTime)
                .page(Page.of(commentQueryRequest.getCurrent(), commentQueryRequest.getPageSize()));
        List<Comment> records = page.getRecords();
        if (CollUtil.isEmpty(records)){
            return null;
        }
        // 4.封装为vo
        List<CommentVO> voList = new ArrayList<>(records.size());
        for (Comment record : records) {
            User user = userService.getById(record.getUserId());
            CommentVO commentVO = getCommentVO(record, user);
            voList.add(commentVO);
        }
        // 创建VO分页对象
        Page<CommentVO> commentVOPage = new Page<>(page.getCurrent(),  page.getSize(), page.getTotal());
        commentVOPage.setRecords(voList);
        return commentVOPage;
    }

    @Override
    public Long addComment(CommentAddRequest commentAddRequest) {
        // 1.获取当前登录用户信息
        UserVO user = UserHolder.getUser();
        // 2.检查评论内容
        String content = commentAddRequest.getContent();
        if (content == null || content.trim().isEmpty()) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "评论内容不能为空");
        }
        // 3.新增评论信息
        Comment comment = BeanUtils.copyBean(commentAddRequest, Comment.class);
        comment.setUserId(user.getId());
        boolean res = save(comment);
        if (!res) {
            throw new DbRuntimeException("新增评论失败-db");
        }
        // 4.更新父评论的子评论数
        if (comment.getParentId() != null && comment.getParentId() > 0) {
            lambdaUpdate()
                    .eq(Comment::getId, comment.getParentId())
                    .setSql("childCount = childCount + 1")
                    .update();
        }
        // 5.更新顶级评论的子评论数
        if (comment.getRootId() != null && comment.getRootId() > 0) {
            lambdaUpdate()
                    .eq(Comment::getId, comment.getRootId())
                    .setSql("childCount = childCount + 1")
                    .update();
        }
        // 5.更新文章的评论数
        communityPostServiceImpl.lambdaUpdate()
                .eq(CommunityPost::getId, comment.getPostId())
                .setSql("commentCount = commentCount + 1")
                .update();

        return comment.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteComment(Long commentId) {
        // 获取当前用户信息
        UserVO user = UserHolder.getUser();
        ThrowUtils.throwIf(user == null, ErrorCode.PARAMS_ERROR, "当前用户不存在");
        // 查询评论是否存在
        Comment comment = this.getById(commentId);
        if (comment == null || comment.getIsDelete() == 1) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "评论不存在");
        }
        Long postId = comment.getPostId();
        CommunityPost post = communityPostService.lambdaQuery()
                .eq(CommunityPost::getId, postId)
                .one();
        if (post == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "评论的文章不存在");
        }
        User postUser = userService.getById(post.getUserId());
        // 检查是否有权限删除
        if (!comment.getUserId().equals(user.getId())) {
            // 检查是否为管理员或者是否为文章作者
            if (!user.getUserRole().equals(UserRoleEnum.ADMIN.getValue()) || !Objects.equals(postUser.getId(), user.getId())) {
                throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "无权删除该评论");
            }
        }
        // 逻辑删除评论
        boolean result = this.removeById(commentId);
        // 更新父评论的子评论数
        if (result && comment.getParentId() != null && comment.getParentId() > 0) {
            boolean update = lambdaUpdate()
                    .eq(Comment::getId, comment.getParentId())
                    .setSql("childCount = childCount - 1")
                    .update();
            if (!update) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR, "更新父评论子评论数失败");
            }
        }
        // 5.更新文章的评论数
        communityPostServiceImpl.lambdaUpdate()
                .eq(CommunityPost::getId, comment.getPostId())
                .setSql("commentCount = commentCount - 1")
                .update();

        return result;
    }

}
